package com.example.myweb.Service.Auth.Impl;

import com.example.myweb.Domain.Entity.*;
import com.example.myweb.Dto.AuthorInfoDTO;
import com.example.myweb.Dto.CreateDynamicRequestDTO;
import com.example.myweb.Dto.DynamicDetailDTO;
import com.example.myweb.Dto.PollResultDTO;
import com.example.myweb.Exception.CustomException;
import com.example.myweb.Repository.JpaRepository.AttachmentRepository;
import com.example.myweb.Repository.JpaRepository.ContentTopicRepository;
import com.example.myweb.Repository.JpaRepository.DynamicRepository;
import com.example.myweb.Repository.JpaRepository.LikeRepository;
import com.example.myweb.Service.Auth.DynamicService;
import com.example.myweb.Service.Auth.PollService;
import com.example.myweb.Service.Auth.TopicService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class DynamicServiceImpl implements DynamicService {

    @Autowired
    private DynamicRepository dynamicRepository;
    @Autowired
    private AttachmentRepository attachmentRepository;
    @Autowired
    private TopicService topicService;
    @Autowired
    private ContentTopicRepository contentTopicRepository;
    @Autowired
    private PollService pollService;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private LikeRepository likeRepository;

    @Override
    @Transactional
    public Dynamic createDynamic(CreateDynamicRequestDTO request, User currentUser) {
        Dynamic newDynamic = new Dynamic();
        newDynamic.setContent(request.getContent());
        newDynamic.setAuthor(currentUser);
        Dynamic savedDynamic = dynamicRepository.save(newDynamic);

        // 处理图片附件
        if (request.getImageUrls() != null && !request.getImageUrls().isEmpty()) {
            List<Attachment> attachments = request.getImageUrls().stream().limit(9).map(imageUrl -> {
                Attachment attachment = new Attachment();
                attachment.setContentType("DYNAMIC");
                attachment.setContentId(savedDynamic.getDynamicId());
                attachment.setType(Attachment.AttachmentType.IMAGE);
                attachment.setUrl(imageUrl);
                return attachment;
            }).collect(Collectors.toList());
            attachmentRepository.saveAll(attachments);
        }

        // 处理话题
        if (request.getTopics() != null && !request.getTopics().isEmpty()) {
            Set<Topic> topics = topicService.findOrCreateTopics(request.getTopics());
            List<ContentTopic> contentTopics = topics.stream().map(topic -> {
                ContentTopic contentTopic = new ContentTopic();
                contentTopic.setContentType(ContentTopic.ContentType.DYNAMIC);
                contentTopic.setContentId(savedDynamic.getDynamicId());
                contentTopic.setTopic(topic);
                // contentTopic.setDynamic(savedDynamic); // 如果有双向关联
                return contentTopic;
            }).collect(Collectors.toList());
            contentTopicRepository.saveAll(contentTopics);
            topicService.incrementTopicHotScore(topics, 2); // 发布动态+2热度
        }

        // 处理投票附件
        if (request.getPoll() != null) {
            Attachment pollAttachment = new Attachment();
            pollAttachment.setContentType("DYNAMIC");
            pollAttachment.setContentId(savedDynamic.getDynamicId());
            pollAttachment.setType(Attachment.AttachmentType.POLL);
            try {
                Map<String, Object> metadata = Map.of(
                        "question", request.getPoll().getQuestion(),
                        "options", request.getPoll().getOptions()
                );
                pollAttachment.setMetadata(objectMapper.writeValueAsString(metadata));
            } catch (JsonProcessingException e) {
                throw new CustomException("创建投票失败", HttpStatus.INTERNAL_SERVER_ERROR);
            }
            attachmentRepository.save(pollAttachment);
        }

        return savedDynamic;
    }

    @Override
    @Transactional(readOnly = true)
    public DynamicDetailDTO getDynamicById(Long dynamicId, User currentUser) {
        Dynamic dynamic = dynamicRepository.findById(dynamicId)
                .orElseThrow(() -> new CustomException("动态不存在", HttpStatus.NOT_FOUND));
        return convertToDetailDto(dynamic, currentUser);
    }

    @Override
    @Transactional(readOnly = true)
    public Page<DynamicDetailDTO> getAllDynamics(Pageable pageable, User currentUser) {
        Page<Dynamic> dynamicPage = dynamicRepository.findAll(pageable);
        // 列表页通常不展示完整的图片和投票，只在详情页展示
        return dynamicPage.map(dyn -> convertToDetailDto(dyn, currentUser));
    }

    // (注意：你之前的 toggleLike 逻辑应该被统一的 LikeService 替代，这里不再包含)

    // --- 辅助转换方法 ---
    private DynamicDetailDTO convertToDetailDto(Dynamic dynamic, User currentUser) {
        DynamicDetailDTO dto = new DynamicDetailDTO();
        dto.setDynamicId(dynamic.getDynamicId());
        dto.setContent(dynamic.getContent());
        dto.setPublishTime(dynamic.getPublishTime());
        dto.setLikeCount(dynamic.getLikeCount());
        dto.setCommentCount(dynamic.getCommentCount());

        dto.setAuthor(new AuthorInfoDTO(
                dynamic.getAuthor().getUserId(),
                dynamic.getAuthor().getNickname(),
                dynamic.getAuthor().getAvatarUrl()
        ));

        // 获取并组装图片和投票
        List<Attachment> attachments = attachmentRepository.findByContentTypeAndContentId("DYNAMIC", dynamic.getDynamicId());

        List<String> imageUrls = attachments.stream()
                .filter(att -> att.getType() == Attachment.AttachmentType.IMAGE)
                .map(Attachment::getUrl)
                .collect(Collectors.toList());
        dto.setImageUrls(imageUrls);

        attachments.stream()
                .filter(att -> att.getType() == Attachment.AttachmentType.POLL)
                .findFirst()
                .ifPresent(pollAttachment -> {
                    PollResultDTO pollResult = pollService.getPollResults(pollAttachment.getAttachmentId(), currentUser);
                    dto.setPoll(pollResult);

                });

        return dto;
    }
    @Override
    @Transactional
    public void deleteDynamic(Long dynamicId, User currentUser) {
        // 1. 查找动态是否存在
        Dynamic dynamicToDelete = dynamicRepository.findById(dynamicId)
                .orElseThrow(() -> new CustomException("动态不存在或已被删除", HttpStatus.NOT_FOUND));

        // 2. 权限校验：确保当前登录用户是动态的作者
        if (!dynamicToDelete.getAuthor().getUserId().equals(currentUser.getUserId())) {
            throw new CustomException("无权删除他人动态", HttpStatus.FORBIDDEN);
        }

        // 3. 执行删除
        // 因为动态也可能关联了评论、点赞、话题、附件等，
        // 最好的方式是在这些关联表的数据库外键上设置 ON DELETE CASCADE。
        // 如果设置了，直接删除Dynamic即可，数据库会自动清理关联数据。
        dynamicRepository.delete(dynamicToDelete);
    }
}
//@Service
//public class DynamicServiceImpl implements DynamicService {
//
//    @Autowired
//    private DynamicRepository dynamicRepository;
//    @Autowired
//    private LikeRepository likeRepository;
//
//    @Autowired
//    private AttachmentRepository attachmentRepository;
//
//    @Override
//    @Transactional
//    public Dynamic createDynamic(CreateDynamicRequestDTO request, User currentUser) {
//        // 1. 创建并保存Dynamic实体
//        Dynamic newDynamic = new Dynamic();
//        newDynamic.setContent(request.getContent());
//        newDynamic.setAuthor(currentUser);
//        Dynamic savedDynamic = dynamicRepository.save(newDynamic);
//
//        // 2. === 新增：处理图片附件 ===
//        if (request.getImageUrls() != null && !request.getImageUrls().isEmpty()) {
//            // 限制图片数量，例如最多9张
//            List<String> validImageUrls = request.getImageUrls().stream().limit(9).collect(Collectors.toList());
//
//            List<Attachment> attachments = validImageUrls.stream()
//                    .map(imageUrl -> {
//                        Attachment attachment = new Attachment();
//                        attachment.setContentType("DYNAMIC"); // 注意这里用字符串，要与Attachment实体定义匹配
//                        attachment.setContentId(savedDynamic.getDynamicId());
//                        attachment.setType(Attachment.AttachmentType.IMAGE);
//                        attachment.setUrl(imageUrl);
//                        return attachment;
//                    })
//                    .collect(Collectors.toList());
//
//            // 批量保存附件
//            attachmentRepository.saveAll(attachments);
//        }
//
//        // 3. 处理话题的逻辑（如果已实现）
//        // ...
//
//        return savedDynamic;
//    }
//
//    @Override
//    @Transactional(readOnly = true)
//    public DynamicDetailDTO getDynamicById(Long dynamicId) {
//        Dynamic dynamic = dynamicRepository.findById(dynamicId)
//                .orElseThrow(() -> new CustomException("动态不存在或已被删除", HttpStatus.NOT_FOUND));
//
//        // === 新增：获取动态关联的图片 ===
//        List<Attachment> attachments = attachmentRepository.findByContentTypeAndContentId("DYNAMIC", dynamicId);
//
//        List<String> imageUrls = attachments.stream()
//                .filter(att -> att.getType() == Attachment.AttachmentType.IMAGE)
//                .map(Attachment::getUrl)
//                .collect(Collectors.toList());
//
//        // 将实体转换为DTO，并传入图片列表
//        return convertToDto(dynamic, imageUrls);
//    }
//
//    @Override
//    public Page<DynamicDetailDTO> getAllDynamics(Pageable pageable) {
//        Page<Dynamic> dynamicPage = dynamicRepository.findAll(pageable);
//
//        // 注意：列表页是否要显示图片？如果需要，这里的逻辑会变得复杂，
//        // 需要先查出所有动态，再批量查出所有动态的图片，然后进行组装。
//        // MVP阶段，可以简化为列表页不显示图片，只在详情页显示。
//        return dynamicPage.map(dyn -> convertToDto(dyn, Collections.emptyList()));
//    }
//
//
//    // === 修改私有辅助方法，使其能接收图片列表 ===
//    private DynamicDetailDTO convertToDto(Dynamic dynamic, List<String> imageUrls) {
//        DynamicDetailDTO dto = new DynamicDetailDTO();
//        dto.setDynamicId(dynamic.getDynamicId());
//        dto.setContent(dynamic.getContent());
//        dto.setPublishTime(dynamic.getPublishTime());
//        dto.setLikeCount(dynamic.getLikeCount());
//        dto.setCommentCount(dynamic.getCommentCount());
//
//        User authorEntity = dynamic.getAuthor();
//        AuthorInfoDTO authorDto = new AuthorInfoDTO(
//                authorEntity.getUserId(),
//                authorEntity.getNickname(),
//                authorEntity.getAvatarUrl()
//        );
//        dto.setAuthor(authorDto);
//
//        // 设置图片列表
//        dto.setImageUrls(imageUrls);
//
//        return dto;
//    }
////    @Override
////    public DynamicDetailDTO getDynamicById(Long dynamicId) {
////        // 1. 从数据库查找，如果找不到，抛出异常
////        Dynamic dynamic = dynamicRepository.findById(dynamicId)
////                .orElseThrow(() -> new CustomException("动态不存在或已被删除", HttpStatus.NOT_FOUND));
////
////        // 2. 将实体(Entity)转换为DTO
////        return convertToDto(dynamic);
////    }
////
////    @Override
////    public Page<DynamicDetailDTO> getAllDynamics(Pageable pageable) {
////        // 1. 调用JPA的分页查询
////        Page<Dynamic> dynamicPage = dynamicRepository.findAll(pageable);
////
////        // 2. 使用Page对象的map功能，将Page<Dynamic>转换为Page<DynamicDetailDTO>
////        return dynamicPage.map(this::convertToDto);
////    }
//
//    /**
//     * 私有辅助方法，用于将Dynamic实体转换为DynamicDetailDTO
//     * @param dynamic 动态实体
//     * @return 动态详情DTO
//     */
//    private DynamicDetailDTO convertToDto(Dynamic dynamic) {
//        DynamicDetailDTO dto = new DynamicDetailDTO();
//        dto.setDynamicId(dynamic.getDynamicId());
//        dto.setContent(dynamic.getContent());
//        dto.setPublishTime(dynamic.getPublishTime());
//        dto.setLikeCount(dynamic.getLikeCount());
//        dto.setCommentCount(dynamic.getCommentCount());
//
//        // 从关联的User实体中提取作者信息
//        User authorEntity = dynamic.getAuthor();
//        AuthorInfoDTO authorDto = new AuthorInfoDTO(
//                authorEntity.getUserId(),
//                authorEntity.getNickname(),
//                authorEntity.getAvatarUrl()
//        );
//        dto.setAuthor(authorDto);
//
//        return dto;
//    }
//    @Override
//    @Transactional // 非常重要！确保操作的原子性
//    public boolean toggleLike(Long dynamicId, User currentUser) {
//        // 1. 检查动态是否存在
//        Dynamic dynamic = dynamicRepository.findById(dynamicId)
//                .orElseThrow(() -> new CustomException("动态不存在", HttpStatus.NOT_FOUND));
//
//        // 2. 查找用户是否已经点赞过该动态
//        Optional<Like> existingLike = likeRepository.findByUserAndTargetTypeAndTargetId(
//                currentUser, Like.LikeTargetType.DYNAMIC, dynamicId
//        );
//
//        if (existingLike.isPresent()) {
//            // --- 如果已点赞，则取消点赞 ---
//            likeRepository.delete(existingLike.get());
//            dynamic.setLikeCount(dynamic.getLikeCount() - 1);
//            dynamicRepository.save(dynamic);
//            return false; // 返回 "未点赞" 状态
//        } else {
//            // --- 如果未点赞，则执行点赞 ---
//            Like newLike = new Like();
//            newLike.setUser(currentUser);
//            newLike.setTargetType(Like.LikeTargetType.DYNAMIC);
//            newLike.setTargetId(dynamicId);
//            likeRepository.save(newLike);
//
//            dynamic.setLikeCount(dynamic.getLikeCount() + 1);
//            dynamicRepository.save(dynamic);
//            return true; // 返回 "已点赞" 状态
//        }
//    }
//}